package com.google.coffeeshop.gui.desktop;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.google.coffeeshop.business.LoginBusiness;
import com.google.coffeeshop.business.SystemBusiness;
import com.google.coffeeshop.gui.desktop.message.CaptionMessages;
import com.google.coffeeshop.gui.desktop.message.ShowMessages;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class LoginPanel extends AbstractBasePanel {

	private static final long serialVersionUID = 1L;

	private AppFrame parent;

	private JTextField tfUsername;
	private JCheckBox chbRememberLogin;
	private JCheckBox chbAutoLogin;
	private JPasswordField tfPassword;
	
	private String usernameRecord = "";
	private String md5PasswordRecord = ""; // md5 string

	public LoginPanel(final AppFrame parent) {
		this.parent = parent;

		GridBagLayout gbl_pnlContent = new GridBagLayout();
		gbl_pnlContent.columnWidths = new int[] {30, 0, 100, 0, 50};
		gbl_pnlContent.rowHeights = new int[] { 30, 30, 0, 0, 30 };
		gbl_pnlContent.columnWeights = new double[] { 0.0, 0.0, 1.0, 0.0, 0.0 };
		gbl_pnlContent.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0 };
		this.setLayout(gbl_pnlContent);

		tfUsername = new JTextField();
		tfUsername.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (KeyEvent.VK_ENTER == e.getKeyCode()) {
					login();
				}
			}
		});
		
				JLabel lblUsername = new JLabel("Username:");
				GridBagConstraints gbc_lblUsername = new GridBagConstraints();
				gbc_lblUsername.fill = GridBagConstraints.BOTH;
				gbc_lblUsername.insets = new Insets(0, 0, 5, 5);
				gbc_lblUsername.gridx = 1;
				gbc_lblUsername.gridy = 0;
				this.add(lblUsername, gbc_lblUsername);
		GridBagConstraints gbc_tfUsername = new GridBagConstraints();
		gbc_tfUsername.gridwidth = 2;
		gbc_tfUsername.fill = GridBagConstraints.BOTH;
		gbc_tfUsername.insets = new Insets(0, 0, 5, 0);
		gbc_tfUsername.gridx = 2;
		gbc_tfUsername.gridy = 0;
		this.add(tfUsername, gbc_tfUsername);
		tfUsername.setColumns(10);

		JButton btnLogin = new JButton(CaptionMessages.LOGIN_BUTTON);
		btnLogin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				login();
			}
		});
		
		chbRememberLogin = new JCheckBox("Remember your login");
		chbRememberLogin.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				JCheckBox checkBox = (JCheckBox)e.getSource();
				if (!checkBox.isSelected()) {
					unselectAutoLoginCheckBox();
					disableAutoLoginCheckBox();
				} else {
					enableAutoLoginCheckBox();
				}
			}

			private void unselectAutoLoginCheckBox() {
				chbAutoLogin.setSelected(Boolean.FALSE);
			}
			
			private void enableAutoLoginCheckBox() {
				chbAutoLogin.setEnabled(Boolean.TRUE);
			}

			private void disableAutoLoginCheckBox() {
				chbAutoLogin.setEnabled(Boolean.FALSE);
			}
		});
		
				JLabel lblPassword = new JLabel("Password:");
				GridBagConstraints gbc_lblPassword = new GridBagConstraints();
				gbc_lblPassword.anchor = GridBagConstraints.EAST;
				gbc_lblPassword.fill = GridBagConstraints.VERTICAL;
				gbc_lblPassword.insets = new Insets(0, 0, 5, 5);
				gbc_lblPassword.gridx = 1;
				gbc_lblPassword.gridy = 1;
				this.add(lblPassword, gbc_lblPassword);
		
		tfPassword = new JPasswordField();
		GridBagConstraints gbc_tfPassword = new GridBagConstraints();
		gbc_tfPassword.gridwidth = 2;
		gbc_tfPassword.insets = new Insets(0, 0, 5, 0);
		gbc_tfPassword.fill = GridBagConstraints.HORIZONTAL;
		gbc_tfPassword.gridx = 2;
		gbc_tfPassword.gridy = 1;
		add(tfPassword, gbc_tfPassword);
		chbRememberLogin.setHorizontalAlignment(SwingConstants.LEFT);
		GridBagConstraints gbc_chbRememberLogin = new GridBagConstraints();
		gbc_chbRememberLogin.gridwidth = 2;
		gbc_chbRememberLogin.anchor = GridBagConstraints.WEST;
		gbc_chbRememberLogin.insets = new Insets(0, 0, 5, 5);
		gbc_chbRememberLogin.gridx = 1;
		gbc_chbRememberLogin.gridy = 2;
		add(chbRememberLogin, gbc_chbRememberLogin);
		
		chbAutoLogin = new JCheckBox("Automatically login when start");
		GridBagConstraints gbc_chbAutoLogin = new GridBagConstraints();
		gbc_chbAutoLogin.anchor = GridBagConstraints.WEST;
		gbc_chbAutoLogin.gridwidth = 2;
		gbc_chbAutoLogin.insets = new Insets(0, 0, 5, 5);
		gbc_chbAutoLogin.gridx = 1;
		gbc_chbAutoLogin.gridy = 3;
		add(chbAutoLogin, gbc_chbAutoLogin);
		GridBagConstraints gbc_btnLogin = new GridBagConstraints();
		gbc_btnLogin.gridwidth = 2;
		gbc_btnLogin.fill = GridBagConstraints.BOTH;
		gbc_btnLogin.insets = new Insets(0, 0, 0, 5);
		gbc_btnLogin.gridx = 1;
		gbc_btnLogin.gridy = 4;
		this.add(btnLogin, gbc_btnLogin);
		
				JButton btnExit = new JButton(CaptionMessages.RESET_BUTTON);
				btnExit.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						reset();
					}
				});
				GridBagConstraints gbc_btnExit = new GridBagConstraints();
				gbc_btnExit.insets = new Insets(0, 0, 0, 5);
				gbc_btnExit.fill = GridBagConstraints.BOTH;
				gbc_btnExit.gridx = 3;
				gbc_btnExit.gridy = 4;
				this.add(btnExit, gbc_btnExit);

		JLabel lblLoginTittle = new JLabel("Login to Amazing Application");
		lblLoginTittle.setHorizontalAlignment(SwingConstants.CENTER);
		lblLoginTittle.setVerticalAlignment(SwingConstants.TOP);
		lblLoginTittle.setFont(new Font("Dialog", Font.BOLD, 21));
		
		loadOptionConfig();
	}

	private void loadOptionConfig() {
		boolean rememberLogin = SystemBusiness.isRememberLogin();
		boolean autoLogin = SystemBusiness.isAutoLogin();
		chbRememberLogin.setSelected(rememberLogin);
		chbAutoLogin.setSelected(autoLogin);
		if (rememberLogin) {
			usernameRecord = SystemBusiness.getUsernameRecord();
			md5PasswordRecord = SystemBusiness.getPasswordRecord();
			
			tfUsername.setText(usernameRecord);
			tfPassword.setText(md5PasswordRecord);
			if (autoLogin) {
				login(usernameRecord, md5PasswordRecord);
			}
		}
	}
	
	public void login() {
		String username = tfUsername.getText();
		char[] password = tfPassword.getPassword();
		if (isSameWithLoginRecords(username, password)) {
			login(this.usernameRecord, this.md5PasswordRecord);
		} else {
			login(username, password);
		}
	}
	
	private boolean isSameWithLoginRecords(final String username, final char[] password) {
		String usernameRecord = this.usernameRecord;
		String md5PasswordRecord = this.md5PasswordRecord;
		return usernameRecord.equals(username) && md5PasswordRecord.equals(String.valueOf(password));
	}
	
	private void login(final String username, final String md5Password) {
		boolean loginSucceeded = LoginBusiness.login(username, md5Password); 
		doLoginActions(loginSucceeded, username, md5Password);
	}
	
	private void login(final String username, final char[] password) {
		boolean loginSucceeded = LoginBusiness.login(username, password);
		doLoginActions(loginSucceeded, username, password);
	}
	
	private void doLoginActions(final boolean loginSucceeded, final String username, final String md5Password) {
		controlLoginActions(loginSucceeded);
		saveLoginConfig(loginSucceeded, username, md5Password, Boolean.FALSE);
	}
	
	private void doLoginActions(final boolean loginSucceeded, final String username, final char[] password) {
		controlLoginActions(loginSucceeded);
		saveLoginConfig(loginSucceeded, username, String.copyValueOf(password), Boolean.TRUE);
	}
	
	private void controlLoginActions(final boolean loginSucceeded) {
		if (loginSucceeded) {
			switchGUIToMainScreen();
		} else {
			JOptionPane.showMessageDialog(this,
					ShowMessages.USERNAME_OR_PASSWORD_WRONGS);
		}
	}
	
	private void saveLoginConfig(boolean loginSucceeded, final String username, final String password, final boolean encrypt) {
		boolean rememberLogin = chbRememberLogin.isSelected();
		boolean autoLogin = chbAutoLogin.isSelected();
		SystemBusiness.saveLoginConfig(rememberLogin, autoLogin);
		if (rememberLogin) {
			if (loginSucceeded) {
				SystemBusiness.saveLoginRecords(username, password, encrypt);
			} else {
				SystemBusiness.saveLoginRecords("", "", Boolean.FALSE);
			}
		}
	}
	
	private void switchGUIToMainScreen() {
		parent.switchView(AppFrame.MAIN_VIEW);
	}

	private void reset() {
		tfUsername.setText("");
		tfPassword.setText("");
	}

}
